Android: add better nullability checks for nullability annotations added in NDK 26#4850
Android: add better nullability checks for nullability annotations added in NDK 26#4850finagolfin wants to merge 1 commit into
Conversation
| munmap(buffer, length) | ||
| } | ||
| #else | ||
| return NSData.NSDataReadResult(bytes: data!, length: mapSize) { buffer, length in |
There was a problem hiding this comment.
As shown in my Bionic link above, mmap() now returns _Nonnull, so this force-unwrap fails.
There was a problem hiding this comment.
It feels rather unfortunate to ifdef around this here instead of at the place we call mmap.
|
@swift-ci test |
| munmap(buffer, length) | ||
| } | ||
| #else | ||
| return NSData.NSDataReadResult(bytes: data!, length: mapSize) { buffer, length in |
There was a problem hiding this comment.
It feels rather unfortunate to ifdef around this here instead of at the place we call mmap.
| do { | ||
| guard fm.fileExists(atPath: _url.path) else { throw _NSErrorWithErrno(ENOENT, reading: true, url: url) } | ||
| _stream = try FileManager.default._fileSystemRepresentation(withPath: _url.path) { fsRep in | ||
| #if os(Android) |
There was a problem hiding this comment.
Similarly here, can we do this by converting the type somehow at the call to fts_open instead of around all uses of the type before that point?
There was a problem hiding this comment.
Maybe there is, I just don't know how to do it. This is simply the best I came up with after seeing these Swift type-casting issues for the first time, and I wanted to ask if there was a better way.
@glbrntt, you recently added similar code to NIO, wdyt?
There was a problem hiding this comment.
NIO wraps all of the syscalls and does any platform-specific shenanigans within the wrapper.
There was a problem hiding this comment.
OK, but that will still require adapting these types for nullability annotations: see my recent patch of your new NIO code for Android.
There was a problem hiding this comment.
re: your patch, does using an implicitly unwrapped optional work for both cases? e.g. [UnsafeMutablePointer<CInterop.PlatformChar>!]
There was a problem hiding this comment.
I get the following error with Swift 5.9.2 on Android AArch64 if I add that to the type signature of libc_fts_open():
swift-nio/Sources/NIOFileSystem/Internal/System Calls/Syscalls.swift:407:14: error: using '!' is not allowed here; perhaps '?' was intended?
_ path: [UnsafeMutablePointer<CInterop.PlatformChar>!],
^ ~
?
error: fatalError
There was a problem hiding this comment.
@glbrntt, is that type what you had in mind, or simply unwrapping the arguments when they are passed in inside ftsOpen()?
There was a problem hiding this comment.
I think that I approached it similarly to what was being suggested - rebinding the memory around the call site.
There was a problem hiding this comment.
These fts_open() changes were no longer needed after swiftlang/swift#74829, so I removed them in #5010.
| // Filesizes are often 64bit even on 32bit systems | ||
| let mapSize = min(length, Int(clamping: statbuf.st_size)) | ||
| #if os(Android) | ||
| // Bionic mmap() now returns _Nonnull, so the force unwrap below isn't needed. |
There was a problem hiding this comment.
@parkera, is this the change you had in mind?
|
@parkera, any further feedback here? |
| return | ||
| } else if errno == ENOTEMPTY { | ||
| #if os(Android) | ||
| let ps = UnsafeMutablePointer<UnsafeMutablePointer<Int8>>.allocate(capacity: 2) |
There was a problem hiding this comment.
Do we really need to duplicate this or can we get away with a rebinding of the memory?
There was a problem hiding this comment.
No longer needed after your swiftlang/swift#74829, so removed in #5010.
| ps.deallocate() | ||
|
|
||
| if stream != nil { | ||
| if let openStream = stream { |
| do { | ||
| guard fm.fileExists(atPath: _url.path) else { throw _NSErrorWithErrno(ENOENT, reading: true, url: url) } | ||
| _stream = try FileManager.default._fileSystemRepresentation(withPath: _url.path) { fsRep in | ||
| #if os(Android) |
There was a problem hiding this comment.
I think that I approached it similarly to what was being suggested - rebinding the memory around the call site.
| return newItemURL.withUnsafeFileSystemRepresentation { (newItemFS) -> Int32? in | ||
| // This is an atomic operation in many OSes, but is not guaranteed to be atomic by the standard. | ||
| if rename(newItemFS, originalFS) == 0 { | ||
| if let newFS = newItemFS, let origFS = originalFS, rename(newFS, origFS) == 0 { |
| // getnameinfo uses size_t for its 4th and 6th arguments. | ||
| private func getnameinfo(_ addr: UnsafePointer<sockaddr>?, _ addrlen: socklen_t, _ host: UnsafeMutablePointer<Int8>?, _ hostlen: socklen_t, _ serv: UnsafeMutablePointer<Int8>?, _ servlen: socklen_t, _ flags: Int32) -> Int32 { | ||
| return Glibc.getnameinfo(addr, addrlen, host, Int(hostlen), serv, Int(servlen), flags) | ||
| guard let saddr = addr else { return -1 } |
There was a problem hiding this comment.
I think that I prefer my approach of changing the signature of the private func.
There was a problem hiding this comment.
Sorry about the delay, been meaning to get to this, hopefully this week.
|
Now that Once that's in 6.0, I will rework this pull for |
This is needed because Bionic recently added a bunch of these annotations. I made sure this pull doesn't break anything by testing most of it with the previous NDK 25c also. I used this patch with others to build the Swift toolchain for my Android CI, finagolfin/swift-android-sdk#122, and the Termux app for Android, which now uses NDK 26b.
@drodriguez or @compnerd, please review.